home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1993 / Internet Info CD-ROM (Walnut Creek) (1993).iso / networking / ip / ka9q / osrc.arc / TCPCMD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-27  |  6.5 KB  |  298 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "timer.h"
  4. #include "mbuf.h"
  5. #include "netuser.h"
  6. #include "internet.h"
  7. #include "tcp.h"
  8. #include "cmdparse.h"
  9.  
  10. extern int Tcp_trace;
  11. extern char *Tcpstates[];
  12. extern char Notval[];
  13. char *pinet();
  14. static int domss(),dortt(),dotcpstat(),dowindow(),dotcpkick();
  15. static int dotcptr(),dotcpreset(),doirtt(),tstat();
  16.  
  17. /* TCP subcommand table */
  18. struct cmds Tcpcmds[] = {
  19.     "irtt",        doirtt,        0, 0,    NULLCHAR,
  20.     "kick",        dotcpkick,    0, 2,    "tcp kick <tcb>",
  21.     "mss",        domss,        0, 0,    NULLCHAR,
  22.     "reset",    dotcpreset,    0, 2,    "tcp reset <tcb>",
  23.     "rtt",        dortt,        0, 3,    "tcp rtt <tcb> <val>",
  24.     "status",    dotcpstat,    0, 0,    NULLCHAR,
  25.     "trace",    dotcptr,    0, 0,    NULLCHAR,
  26.     "window",    dowindow,    0, 0,    NULLCHAR,
  27.     NULLCHAR,    NULLFP,        0, 0,    "tcp subcommands: irtt kick mss reset rtt status trace window",
  28. };
  29. int
  30. dotcp(argc,argv,envp)
  31. int argc;
  32. char *argv[];
  33. void *envp;
  34. {
  35.     return subcmd(Tcpcmds,argc,argv,envp);
  36. }
  37. static int
  38. dotcptr(argc,argv)
  39. int argc;
  40. char *argv[];
  41. {
  42.     if(argc < 2)
  43.         printf("TCP state tracing %s\n",Tcp_trace ? "on":"off");
  44.     else {
  45.         if(strcmp(argv[1],"on") == 0)
  46.             Tcp_trace = 1;
  47.         else
  48.             Tcp_trace = 0;
  49.     }
  50.     return 0;
  51. }
  52.  
  53. /* Eliminate a TCP connection */
  54. static int
  55. dotcpreset(argc,argv)
  56. int argc;
  57. char *argv[];
  58. {
  59.     register struct tcb *tcb;
  60.  
  61.     tcb = (struct tcb *)ltop(htol(argv[1]));
  62.     if(!tcpval(tcb)){
  63.         printf(Notval);
  64.         return 1;
  65.     }
  66.     close_self(tcb,RESET);
  67.     return 0;
  68. }
  69.  
  70. /* Set initial round trip time for new connections */
  71. static int
  72. doirtt(argc,argv)
  73. int argc;
  74. char *argv[];
  75. {
  76.     struct tcp_rtt *tp;
  77.  
  78.     if(argc < 2){
  79.         printf("default irtt: %lu\n",Tcp_irtt);
  80.         for(tp = &Tcp_rtt[0];tp < &Tcp_rtt[RTTCACHE];tp++){
  81.             if(tp->addr != 0){
  82.                 printf("%s: srtt %lu mdev %lu\n",
  83.                     inet_ntoa(tp->addr),
  84.                     tp->srtt,tp->mdev);
  85.             }
  86.         }
  87.     } else if(*argv[1] == 'f'){
  88.         /* Flush RTT cache */
  89.         for(tp = &Tcp_rtt[0];tp < &Tcp_rtt[RTTCACHE];tp++)
  90.             tp->addr = 0;
  91.     } else 
  92.         Tcp_irtt = atol(argv[1]);
  93.  
  94.     return 0;
  95. }
  96.  
  97. /* Set smoothed round trip time for specified TCB */
  98. static int
  99. dortt(argc,argv)
  100. int argc;
  101. char *argv[];
  102. {
  103.     register struct tcb *tcb;
  104.  
  105.     tcb = (struct tcb *)ltop(htol(argv[1]));
  106.     if(!tcpval(tcb)){
  107.         printf(Notval);
  108.         return 1;
  109.     }
  110.     tcb->srtt = atol(argv[2]);
  111.     return 0;
  112. }
  113.  
  114. /* Force a retransmission */
  115. static int
  116. dotcpkick(argc,argv)
  117. int argc;
  118. char *argv[];
  119. {
  120.     register struct tcb *tcb;
  121.  
  122.     tcb = (struct tcb *)ltop(htol(argv[1]));
  123.     if(kick_tcp(tcb) == -1){
  124.         printf(Notval);
  125.         return 1;
  126.     }
  127.     return 0;
  128. }
  129.  
  130. /* Set default maximum segment size */
  131. static int
  132. domss(argc,argv)
  133. int argc;
  134. char *argv[];
  135. {
  136.     if(argc < 2)
  137.         printf("%u\n",Tcp_mss);
  138.     else
  139.         Tcp_mss = atoi(argv[1]);
  140.     return 0;
  141. }
  142.  
  143. /* Set default window size */
  144. static int
  145. dowindow(argc,argv)
  146. int argc;
  147. char *argv[];
  148. {
  149.     if(argc < 2)
  150.         printf("%u\n",Tcp_window);
  151.     else
  152.         Tcp_window = atoi(argv[1]);
  153.     return 0;
  154. }
  155.  
  156. /* Display status of TCBs */
  157. static int
  158. dotcpstat(argc,argv)
  159. int argc;
  160. char *argv[];
  161. {
  162.     register struct tcb *tcb;
  163.  
  164.     if(argc < 2){
  165.         tstat();
  166.     } else {
  167.         tcb = (struct tcb *)ltop(htol(argv[1]));
  168.         if(tcpval(tcb))
  169.             st_tcp(tcb);
  170.         else
  171.             printf(Notval);
  172.     }
  173.     return 0;
  174. }
  175.  
  176. /* Dump TCP stats and summary of all TCBs
  177. /*     &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State
  178.  *     1234     0     0  xxx.xxx.xxx.xxx:xxxxx  xxx.xxx.xxx.xxx:xxxxx  Established
  179.  */
  180. static int
  181. tstat()
  182. {
  183.     register int i;
  184.     register struct tcb *tcb;
  185.  
  186.     printf("conout %u conin %u reset out %u runt %u chksum err %u bdcsts %u\n",
  187.         Tcp_stat.conout,Tcp_stat.conin,Tcp_stat.resets,Tcp_stat.runt,
  188.         Tcp_stat.checksum,Tcp_stat.bdcsts);
  189.     printf("    &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State\n");
  190.     for(i=0;i<NTCB;i++){
  191.         for(tcb=Tcbs[i];tcb != NULLTCB;tcb = tcb->next){
  192.             printf("%8lx%6u%6u  ",ptol(tcb),tcb->rcvcnt,tcb->sndcnt);
  193.             printf("%-23s",pinet(&tcb->conn.local));
  194.             printf("%-23s",pinet(&tcb->conn.remote));
  195.             printf("%-s",Tcpstates[tcb->state]);
  196.             if(tcb->state == LISTEN && tcb->flags.clone)
  197.                 printf(" (S)");
  198.             printf("\n");
  199.         }
  200.     }
  201.     return 0;
  202. }
  203. /* Dump a TCP control block in detail */
  204. void
  205. st_tcp(tcb)
  206. struct tcb *tcb;
  207. {
  208.     int32 sent,recvd;
  209.  
  210.     if(tcb == NULLTCB)
  211.         return;
  212.     /* Compute total data sent and received; take out SYN and FIN */
  213.     sent = tcb->snd.una - tcb->iss;    /* Acknowledged data only */
  214.     recvd = tcb->rcv.nxt - tcb->irs;
  215.     switch(tcb->state){
  216.     case LISTEN:
  217.     case SYN_SENT:        /* Nothing received or acked yet */
  218.         sent = recvd = 0;    
  219.         break;
  220.     case SYN_RECEIVED:
  221.         recvd--;    /* Got SYN, no data acked yet */
  222.         sent = 0;
  223.         break;
  224.     case ESTABLISHED:    /* Got and sent SYN */
  225.     case FINWAIT1:        /* FIN not acked yet */
  226.         sent--;
  227.         recvd--;
  228.         break;
  229.     case FINWAIT2:        /* Our SYN and FIN both acked */
  230.         sent -= 2;
  231.         recvd--;
  232.         break;
  233.     case CLOSE_WAIT:    /* Got SYN and FIN, our FIN not yet acked */
  234.     case CLOSING:
  235.     case LAST_ACK:
  236.         sent--;
  237.         recvd -= 2;
  238.         break;
  239.     case TIME_WAIT:        /* Sent and received SYN/FIN, all acked */
  240.         sent -= 2;
  241.         recvd -= 2;
  242.         break;
  243.     }
  244.     printf("Local: %s",pinet(&tcb->conn.local));
  245.     printf(" Remote: %s",pinet(&tcb->conn.remote));
  246.     printf(" State: %s\n",Tcpstates[tcb->state]);
  247.     printf("      Init seq    Unack     Next Resent CWind Thrsh  Wind  MSS Queue      Total\n");
  248.     printf("Send:");
  249.     printf("%9lx",tcb->iss);
  250.     printf("%9lx",tcb->snd.una);
  251.     printf("%9lx",tcb->snd.nxt);
  252.     printf("%7lu",tcb->resent);
  253.     printf("%6u",tcb->cwind);
  254.     printf("%6u",tcb->ssthresh);
  255.     printf("%6u",tcb->snd.wnd);
  256.     printf("%5u",tcb->mss);
  257.     printf("%6u",tcb->sndcnt);
  258.     printf("%11lu\n",sent);
  259.  
  260.     printf("Recv:");
  261.     printf("%9lx",tcb->irs);
  262.     printf("         ");
  263.     printf("%9lx",tcb->rcv.nxt);
  264.     printf("%7lu",tcb->rerecv);
  265.     printf("      ");
  266.     printf("      ");
  267.     printf("%6u",tcb->rcv.wnd);
  268.     printf("     ");
  269.     printf("%6u",tcb->rcvcnt);
  270.     printf("%11lu\n",recvd);
  271.  
  272.     if(tcb->reseq != (struct reseq *)NULL){
  273.         register struct reseq *rp;
  274.  
  275.         printf("Reassembly queue:\n");
  276.         for(rp = tcb->reseq;rp != (struct reseq *)NULL; rp = rp->next){
  277.             printf("  seq x%lx %u bytes\n",rp->seg.seq,rp->length);
  278.         }
  279.     }
  280.     if(tcb->backoff > 0)
  281.         printf("Backoff %u ",tcb->backoff);
  282.     if(tcb->flags.retran)
  283.         printf("Retrying ");
  284.     switch(tcb->timer.state){
  285.     case TIMER_STOP:
  286.         printf("Timer stopped ");
  287.         break;
  288.     case TIMER_RUN:
  289.         printf("Timer running (%ld/%ld ms) ",
  290.          (long)MSPTICK * read_timer(&tcb->timer),
  291.          (long)MSPTICK * dur_timer(&tcb->timer));
  292.         break;
  293.     case TIMER_EXPIRE:
  294.         printf("Timer expired ");
  295.     }
  296.     printf("SRTT %ld ms Mean dev %ld ms\n",tcb->srtt,tcb->mdev);
  297. }
  298.